#ifndef FILE_DOWNLOAD_H
#define FILE_DOWNLOAD_H
#include <vector>
#include <list> //用作每个写入磁盘进行保存任务队列
#include "../message_struct/message.pb.h"   //上传的结构
#include <pthread.h>
#include "../../include/inherit_socket.h"
#include <map>

//这是针对于file_item而言的
#define WORK_ITEM_ACTIVE 1
#define WORK_ITEM_SLEEP  0

//整个文件下载的启停
#define FILE_DOWNLOAD_END  0
#define FILE_DOWNLOAD_RUNNING 1

//文件传输结构


class file_item{
public:
    int opened_fd;  //当前传输文件的fd
    long long file_size;    //文件原本大小
    std::string file_servername;    //服务器上的所在文件路径，等待客户端发送完响应后再依旧这个打开 
    int seq;
    long long  transformed_size;    //当前已传输大小
    // int state;  //    is_active  用于判断是否要发送，接收到客户端的回应后，才会变为可以执行发送逻辑
    
};


//任务结构---针对于用户而言的
class work_item{
public:
    //这样带来断点续传难搞了--可以这样，根据用户的请求，依旧查询出所有要下载的文件，也尝试发一个切片，
    //客户端接收到切片后，判断指定路径下有无该文件，那么等待客户端的响应，客户端这里还能做一个文件的创建，打开，服务器再做下一步
    connection_p con_p; 
    int work_id;    //客户端的下载任务的id,客户端便于区分任务包，这个值由客户端生成
    //上面两个的组合是任务的唯一标识，能够定位到work_item
    int icurrentsequence;   //判断该连接的有效性与否

    bool is_active; //该任务是否活跃------客户端发送刺探报文的响应后,才会变为活跃，毕竟是以一个work_item为单位的--有点多余了，毕竟只有活跃了，才会放入task_map进行发送
    std::string client_request; //客户端的文件下载请求

    std::map<std::string,file_item*> work_item_map; //根据文件路径与名字，找到对应的file_item,更改状态，等操作  key=client_filename

    ~work_item();   //在这个析构调用中，delete掉file_item
    
};


class file_downloader;
//下载任务的线程结构
class file_downloader_thread_item{
public:
    
    pthread_t handler;  //线程句柄
    std::map<std::pair<connection_p,int>,work_item*>task_map; //任务列表,通过connection_p与work_id来作为唯一标识
    std::map<std::pair<connection_p,int>,work_item*>tmp_task_map;   //也有数据竞争
    pthread_mutex_t mutex;
    pthread_mutex_t tmp_task_map_mutex; //专门用于tmp_task_map任务加入的互斥
    pthread_cond_t cond;
    bool is_running;
    //bool is_having_active_item_in_tmp_task_map;
    file_downloader * instance_downloader;
    file_downloader_thread_item(file_downloader *);
    ~file_downloader_thread_item(); //用于结束线程的，并将任务队列里的东西delete掉

};

//这个类要做成单例类
class file_downloader{
public:
    static file_downloader * get_instance(){
        if(file_downloader::true_file_downloader==nullptr){
            file_downloader::true_file_downloader=new file_downloader();
            static for_file_downloader just_for_delete;
        }
        return file_downloader::true_file_downloader;
    }

    file_downloader_thread_item * get_one_thread_item(int user_id); //根据id找到目标线程,也不是很合适,暂定是work_id
    static void * thread_func(void * true_file_downloader_thread_item); //执行任务的线程体
    ~file_downloader(); //结束下载线程
private:
    std::vector<file_downloader_thread_item*> downloaders;  //线程句柄数组
    int downloader_num; //文件下载线程个数
    
    file_downloader();  //构造函数
    bool file_download_flag;   //是否启停的标志
    static file_downloader * true_file_downloader; //实例指针
    void end_downloader();  //用于结束全部的下载任务线程

    //内部类，用于到时候回收该类所管控的所有资源
    class for_file_downloader{
    public:
        ~for_file_downloader(){

            if(file_downloader::true_file_downloader){
                delete file_downloader::true_file_downloader;
                file_downloader::true_file_downloader=nullptr;
            }
        }
    };

};


#endif